package com.xyazm.order.statemachine.action.order.fulfill;

import com.xyazm.common.enums.OrderStatusChangeEnum;
import com.xyazm.common.enums.OrderStatusEnum;
import com.xyazm.order.dao.OrderInfoDAO;
import com.xyazm.order.domain.dto.AfterFulfillDTO;
import com.xyazm.order.domain.dto.OrderInfoDTO;
import com.xyazm.order.domain.entity.OrderInfoDO;
import com.xyazm.order.mapstruct.OrderApiMapstruct;
import com.xyazm.order.statemachine.action.OrderStateAction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;

/**
 * 履约后置标准流程
 * @author xuyou
 * @date 2023年02月09日 20:21
 */
public abstract class AbstractAfterFulfillAction extends OrderStateAction<AfterFulfillDTO> {

    @Resource
    private TransactionTemplate transactionTemplate;
    @Autowired
    protected OrderInfoDAO orderInfoDAO;
    /**
     * 状态变更操作
     * @author xuyou
     * 2023-02-09 20:23
     * @param event
     * @param context
    */
    @Override
    protected OrderInfoDTO onStateChangeInternal(OrderStatusChangeEnum event, AfterFulfillDTO context) {
        //  @Transactional无法生效，需要用编程式事务
        return transactionTemplate.execute(transactionStatus -> {
            // 1、查询订单
            OrderInfoDO orderInfoDO = orderInfoDAO.getByOrderId(context.getOrderId());
            if (null == orderInfoDO) {
                return null;
            }
            // 2、校验订单状态
            OrderStatusEnum orderStatus = OrderStatusEnum.getByCode(orderInfoDO.getOrderStatus());
            // 此次需要处理的订单状态
            if (!handleStatus().equals(orderStatus)) {
                return null;
            }
            // 3、执行具体的业务逻辑
            doExecute(context, orderInfoDO);
            // 4、更新订单状态
            changeOrderStatus(context, orderInfoDO);
            // 5、增加操作日志
            saveOrderOperateLog(context);
            return OrderApiMapstruct.INSTANCE.convertOrderInfoDTO(orderInfoDO);
        });
    }

    /**
     * 增加操作日志
     * @author xuyou
     * 2023-02-09 20:34
     * @param context
    */
    private void saveOrderOperateLog(AfterFulfillDTO context) {
        OrderStatusChangeEnum statusChange = context.getStatusChange();
        Integer operateType = statusChange.getOperateType().getCode();
        String remark = statusChange.getOperateType().getMsg() +
                ",订单状态变更:" + statusChange.getFromStatus() + "-" + statusChange.getToStatus();
        super.saveOrderOperateLog(context.getOrderId(), operateType, statusChange.getFromStatus().getCode()
                , statusChange.getToStatus().getCode(), remark);
    }

    /**
     * 更新订单状态
     */
    private void changeOrderStatus(AfterFulfillDTO afterFulfillDTO,OrderInfoDO orderInfoDO) {
        OrderStatusChangeEnum statusChange = afterFulfillDTO.getStatusChange();
        orderInfoDAO.updateOrderStatus(orderInfoDO.getOrderId(), statusChange.getFromStatus().getCode()
                , statusChange.getToStatus().getCode());
    }

    /**
     * 执行具体的业务逻辑
     * @author xuyou
     * 2023-02-09 20:26
     * @param context
     * @param orderInfoDO
    */
    protected void doExecute(AfterFulfillDTO context, OrderInfoDO orderInfoDO) {
        // 默认空实现
    }

    /**
     * @return 自己需要处理的订单状态
     */
    protected abstract OrderStatusEnum handleStatus();
}
